/* 
 * Copyright (C) 2012 UTSChedule
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package utsc.apps.utschedule.ui.activities;

import java.util.ArrayList;
import java.util.List;

import com.actionbarsherlock.app.SherlockActivity;
import utsc.apps.utschedule.R;
import utsc.apps.utschedule.classes.Assignment;
import utsc.apps.utschedule.classes.Calculator;
import utsc.apps.utschedule.classes.Course;
import utsc.apps.utschedule.classes.Exam;
import utsc.apps.utschedule.classes.GenericTask;
import utsc.apps.utschedule.ui.ExpandableListFragment;
import utsc.apps.utschedule.ui.activities.adapters.CalculatorListAdapter;
import utsc.apps.utschedule.ui.interfaces.TimetableActivity;
import utsc.apps.utschedule.util.database.DatabaseManager;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.TextView;

/**
 * This is a custom list fragment to display all the {@link GenericTask tasks} for all {@link Course Courses} without tutorials.
 * It also displays the current sessional GPA as well.
 */
public class CalculatorListFragment extends ExpandableListFragment implements OnClickListener {
	
	public static final String TAG="utsc.apps.utschedule.ui.activities.CalculatorListFragment";
	public int _timetableID;
	public static final String ARGS_TIMETABLEID="timetableID";
	public CalculatorListAdapter _adapter;
	private boolean _updated;
	private double _gpa;
	private Button _btnForecast;
	/**
	 * This is used to store the result course id from detail view, so we can refresh the list accordingly.
	 */
	private int _resultCourseID;
	private TextView _gpaVale;
	
	/**
	 * This interface is used as a delegate that a
	 * {@link CalculatorListFragment CalculatorListFragment} can use its parent
	 * {@link SherlockActivity Activity} to handle different actions.
	 */
	public static interface OnForecastListener{
		public void onGPAForecast(ArrayList<Course> courses);
		public void onCourseForecast(Course selectedCourse);
		public void onForecastAction();
	}
	/**
	 * The empty constructor is required.
	 */
	public  CalculatorListFragment() {
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment_calculator_list, null);
	}

	/**
	 * This is the recommended way to create a new fragment. It takes in a timetable id as an argument.
	 * @param timetableID
	 * @return
	 */
	public static CalculatorListFragment newInstance(int timetableID){
		Bundle args=new Bundle();
		args.putInt(ARGS_TIMETABLEID, timetableID);
		CalculatorListFragment fragment=new CalculatorListFragment();
		fragment.setArguments(args);
		return fragment;
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		View curView = getView();
		_gpaVale = (TextView) curView.findViewById(R.id.txt_list_gpa);
		_btnForecast= (Button) curView.findViewById(R.id.btn_forecast);
		//move the group indicator from the left to right
		DisplayMetrics metrics = new DisplayMetrics();
	        getSherlockActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
	        int width = metrics.widthPixels;
		ExpandableListView listView=getExpandableListView();
		listView.setCacheColorHint(Color.TRANSPARENT);
		listView.setGroupIndicator(getResources().getDrawable(R.drawable.list_group_indicator));
		listView.setIndicatorBounds(width-60, width);
		Bundle args=getArguments();
		if (args!=null) {
			_timetableID=args.getInt(ARGS_TIMETABLEID);
		}
		_btnForecast.setOnClickListener(this);
		//setup the underlying listview
		onContentChanged();
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode==SherlockActivity.RESULT_OK) {
			_updated=false;
			_resultCourseID=data.getIntExtra("AssignmentCourseForResult",0);
		}
		//refresh the gpa all the time
		updateGPA();
	}

	@Override
	public void onResume() {
		super.onResume();
		if (_adapter==null) {
			ArrayList<Course> courses=new ArrayList<Course>(DatabaseManager.getInstance(getSherlockActivity()).getCoursesWithoutTutorials(_timetableID));
			_adapter=new CalculatorListAdapter(courses, getSherlockActivity());
			if (courses==null || courses.isEmpty()) {
				setEmptyText("No Courses Found!");
			}else {
				updateGPA();
			}
			setListAdapter(_adapter);
			
		}else {
			if (_resultCourseID!=0&&!_updated) {
				DatabaseManager.getInstance(getSherlockActivity());
				_adapter.notifyDataSetChanged(_resultCourseID);
				updateGPA();
			}
		}
	}
	
	public void setListAdapter(CalculatorListAdapter adapter) {
		super.setListAdapter(adapter);
	}
	
	@Override
	public CalculatorListAdapter getExpandableListAdapter() {
		return (CalculatorListAdapter) super.getExpandableListAdapter();
	}
	
	@Override
	public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
		GenericTask task=getExpandableListAdapter().getChild(groupPosition, childPosition);
		//if the selected child is a task object,
		//open the associated detail view
		if (task!=null) {
			Intent showDetailIntent=null;
			if (task instanceof Assignment) {
				showDetailIntent=new Intent(getSherlockActivity(), AssignmentDetailActivity.class);
				showDetailIntent.putExtra("CourseAssignment", ((Assignment)task).get_course().get_courseID());
				showDetailIntent.putExtras(((Assignment)task).getObjectIntent());
				startActivityForResult(showDetailIntent, TimetableActivity.RESULT_UPDATE_ASSIGNMENT);
			}else {
				showDetailIntent=new Intent(getSherlockActivity(), ExamDetailActivity.class);
				showDetailIntent.putExtra("CourseExam", ((Exam)task).get_course().get_courseID());
				showDetailIntent.putExtras(((Exam)task).getObjectIntent());
				startActivityForResult(showDetailIntent, TimetableActivity.RESULT_UPDATE_EXAM);
			}
		}
		//otherwise, the "course grade forecast" button was clicked
		else {
			((OnForecastListener)getSherlockActivity()).onCourseForecast(getExpandableListAdapter().getGroup(groupPosition));
		}
		return true;
	}
	
	/**
	 * A helper method to refresh the sessional GPA view.
	 */
	private void updateGPA() {
		//get all the courses from the adapter
		ArrayList<Course> courses=_adapter.get_courses();
		DatabaseManager dbManager=DatabaseManager.getInstance(getSherlockActivity());
		//loop through the course list
		//and setup the task list of each course
		//so each course grade is updated 
		for (Course course : courses) {
			if (course.get_taskList()==null) {
				List<GenericTask> tasks=dbManager.getCourseTasks(course.get_courseID());
				if (tasks!=null) {
					course.set_taskList(new ArrayList<GenericTask>(tasks));
				}else {
					course.set_taskList(new ArrayList<GenericTask>());
				}
			}
		}
		//use the calculator object to calculate the session gpa for us
		Calculator gpaCalc=new Calculator(courses);
		_gpa=gpaCalc.get_GPA();
		
		String gpaOut = Double.toString(this._gpa);
		if (gpaOut.length() > 4)
			gpaOut = gpaOut.substring(0, 4);				
		else if (gpaOut.length() < 4)
			gpaOut += "0";
		_gpaVale.setText(gpaOut);
	}
	
	public double get_gpa() {
		return _gpa;
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		//catch the "GPA forecast" button click action
		case R.id.btn_forecast:
			((OnForecastListener)getSherlockActivity()).onGPAForecast(_adapter.get_courses());
			break;

		default:
			break;
		}
	}
}
